/*
    SUSAN® - Sole of Unix Save ANything

   

   

   

   
*/
#if defined(HAVE_MINGW)
#include "include/susan.h"
#include "gtest/gtest.h"
#else
#include "gtest/gtest.h"
#include "include/susan.h"
#endif

#include "include/jcr.h"
#include "include/make_unique.h"
#include "lib/thread_specific_data.h"

#include <thread>

TEST(thread_specific_data, setup_and_readout_data_one_thread)
{
  std::unique_ptr<JobControlRecord> jcr(std::make_unique<JobControlRecord>());
  jcr->JobId = 123;

  SetJcrInThreadSpecificData(jcr.get());

  JobControlRecord* jcr_same = GetJcrFromThreadSpecificData();
  EXPECT_EQ(jcr.get(), jcr_same);

  uint32_t jobid = GetJobIdFromThreadSpecificData();
  EXPECT_EQ(jobid, 123);

  RemoveJcrFromThreadSpecificData(jcr.get());
  JobControlRecord* jcr_invalid = GetJcrFromThreadSpecificData();
  EXPECT_EQ(jcr_invalid, nullptr);
}

static std::vector<uint32_t> thread_jobids(100);

static void test_thread(uint32_t index)
{
  std::unique_ptr<JobControlRecord> jcr(std::make_unique<JobControlRecord>());
  jcr->JobId = 123 + index;

  SetJcrInThreadSpecificData(jcr.get());
  std::this_thread::sleep_for(std::chrono::milliseconds(3));

  JobControlRecord* jcr_same = GetJcrFromThreadSpecificData();
  EXPECT_EQ(jcr.get(), jcr_same);

  uint32_t jobid = GetJobIdFromThreadSpecificData();

  thread_jobids[index] = jobid;
}

TEST(thread_specific_data, setup_and_readout_data_multiple_threads)
{
  std::vector<std::thread> threads;

  for (std::size_t i = 0; i < thread_jobids.size(); i++) {
    threads.emplace_back(test_thread, i);
  }

  for (std::size_t i = 0; i < thread_jobids.size(); i++) {
    threads[i].join();
    EXPECT_EQ(thread_jobids[i], 123 + i);
  }
}
